package modules

import "sync"

type IModule interface {
	OnInit() error
	OnDestroy()
	Run(closeSig chan bool)
}

type module struct {
	m        IModule
	closeSig chan bool // 用于停止正在进行的任务
	wg       sync.WaitGroup
}

var mods []*module

func run(m *module) {
	defer func() {
		if err := recover(); err != nil {
			// todo log
		}
	}()
	m.m.Run(m.closeSig)
	m.wg.Done()
}

func destroy(m *module) {
	defer func() {
		if err := recover(); err != nil {
			// todo log
		}
	}()
	m.m.OnDestroy()
}

func Register(m IModule) {
	mod := new(module)
	mod.m = m
	mod.closeSig = make(chan bool)

	mods = append(mods, mod)
}

// Init 方法在系统启动时候调用
// 依次运行每个模块，
func Init() error {
	var err error
	for i := 0; i < len(mods); i++ {
		err = mods[i].m.OnInit()
		if err != nil {
			return err
		}
	}

	for i := 0; i < len(mods); i++ {
		m := mods[i]
		m.wg.Add(1)

		go run(m)
	}

	return nil
}

func Destroy() {
	for i := len(mods) - 1; i >= 0; i-- {
		m := mods[i]
		m.closeSig <- true
		m.wg.Wait()
		destroy(m)
	}
}
